package Notify;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class ShareDataOne//资源类
{
    private int number = 0;//初始值为零的一个变量
    private int i = 1;
    private String  [] ary = new String[] {"aa","bb","cc","dd","e","f","j","h","i","j","k","L","m","n"
            ,"o","p","q","r","s","t","u","v","w","s","y","z"};
    private  int a = 0;
    private Lock lock = new ReentrantLock();  //锁
    Condition c1 = lock.newCondition();
    Condition c2 = lock.newCondition();

    public   void increment()   {
        lock.lock();
        try {   //1判断
         while (a !=0 ) {
                c1.await();
         }
        //2干活
         for (int i = 0; i < 2; i++) {
            ++number;

            System.out.print(number);
         }


        //3通知
            a=1;
        c2.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public   void decrement()
    {
        lock.lock();
        try {  // 1判断
        while (a != 1) {
            c2.await();
        }
            // 2干活
         ++i;

         int   num = number-i;

         System.out.println(ary[num]+",");

        // 3通知

         a =0;
        c1.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

/**
 *
 * @Description:
 *现在两个线程，
 * 可以操作初始值为零的一个变量，
 * 实现一个线程对该变量加1，一个线程对该变量减1，
 * 交替，来10轮。
 * @author xialei
 *
 *  * 笔记：Java里面如何进行工程级别的多线程编写
 * 1 多线程变成模板（套路）-----上
 *     1.1  线程    操作    资源类
 *     1.2  高内聚  低耦合
 * 2 多线程变成模板（套路）-----下
 *     2.1  判断
 *     2.2  干活
 *     2.3  通知

 */
public class NotifyWaitDemoOne
{
    public static void main(String[] args)
    {
        ShareDataOne sd = new ShareDataOne();
        new Thread(() -> {
            for (int i = 1; i < 27; i++) {
                try {
                    sd.increment();
                } catch ( Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }, "A").start();
//        new Thread(() -> {
//            for (int i = 1; i < 25; i++) {
//                try {
//                    sd.increment();
//                } catch (InterruptedException e) {
//                    // TODO Auto-generated catch block
//                    e.printStackTrace();
//                }
//            }
//        }, "B").start();
        new Thread(() -> {
            for (int i = 1; i < 27; i++) {
                try {
                    sd.decrement();
                } catch ( Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }, "C").start();
//        new Thread(() -> {
//            for (int i = 1; i < 10; i++) {
//                try {
//                    sd.decrement();
//                } catch (InterruptedException e) {
//                    // TODO Auto-generated catch block
//                    e.printStackTrace();
//                }
//            }
//        }, "D").start();
    }
}
/*
 * *
 * 2 多线程变成模板（套路）-----下
 *     2.1  判断
 *     2.2  干活
 *     2.3  通知
 * 3 防止虚假唤醒用while
 *
 *
 * */


